<?php

namespace App\Models;

use App\Service\Base\Model;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Str;

class User extends Model
{
    // 用户管理
    protected $table = 'user';

    // 缓存字段，用于搜索绑定的字段
    protected $cacheFields = ["id", "status",];

    // {"id":"编号","score":"积分","username":"用户名（唯一且不变，用于阿特@操作）","password":"密码","nickname":"昵称（企业认证名称，因为程序中已经使用，所以不修改字段名）","head_img":"头像","mobile":"手机号","email":"邮箱","sex":"0-保密1-男 2-女","city":"所在城市","reg_ip":"注册ip","last_ip":"上次登录ip","last_time":"上次登录时间","sign":"个性签名","status":"状态 0-禁用 1-正常 -1-删除","openid":"微信openid","from_uid":"邀请人","money":"资金余额","is_auth":"是否认证（1-是）","auth_type":"认证类型","auth_name":"认证名称","auth_time":"认证时间","auth_id":"认证ID（认证后写入）","end_time":"认证结束时间","verify":"是否审核（认证用户才需要审核）（1-是,审核通过，2-审核不通过）","ctime":"创建时间","mtime":"修改时间"}

    // array ( 'id' => '$this->getData("id", null, "trim")', 'score' => '$this->getData("score", null, "trim")', 'username' => '$this->getData("username", null, "trim")', 'password' => '$this->getData("password", null, "trim")', 'nickname' => '$this->getData("nickname", null, "trim")', 'head_img' => '$this->getData("head_img", null, "trim")', 'mobile' => '$this->getData("mobile", null, "trim")', 'email' => '$this->getData("email", null, "trim")', 'sex' => '$this->getData("sex", null, "trim")', 'city' => '$this->getData("city", null, "trim")', 'reg_ip' => '$this->getData("reg_ip", null, "trim")', 'last_ip' => '$this->getData("last_ip", null, "trim")', 'last_time' => '$this->getData("last_time", null, "trim")', 'sign' => '$this->getData("sign", null, "trim")', 'status' => '$this->getData("status", null, "trim")', 'openid' => '$this->getData("openid", null, "trim")', 'from_uid' => '$this->getData("from_uid", null, "trim")', 'money' => '$this->getData("money", null, "trim")', 'is_auth' => '$this->getData("is_auth", null, "trim")', 'auth_type' => '$this->getData("auth_type", null, "trim")', 'auth_name' => '$this->getData("auth_name", null, "trim")', 'auth_time' => '$this->getData("auth_time", null, "trim")', 'auth_id' => '$this->getData("auth_id", null, "trim")', 'end_time' => '$this->getData("end_time", null, "trim")', 'verify' => '$this->getData("verify", null, "trim")', 'ctime' => '$this->getData("ctime", null, "trim")', 'mtime' => '$this->getData("mtime", null, "trim")', )

    // $id = $this->getData("id", null, 'trim'); $score = $this->getData("score", null, 'trim'); $username = $this->getData("username", null, 'trim'); $password = $this->getData("password", null, 'trim'); $nickname = $this->getData("nickname", null, 'trim'); $head_img = $this->getData("head_img", null, 'trim'); $mobile = $this->getData("mobile", null, 'trim'); $email = $this->getData("email", null, 'trim'); $sex = $this->getData("sex", null, 'trim'); $city = $this->getData("city", null, 'trim'); $reg_ip = $this->getData("reg_ip", null, 'trim'); $last_ip = $this->getData("last_ip", null, 'trim'); $last_time = $this->getData("last_time", null, 'trim'); $sign = $this->getData("sign", null, 'trim'); $status = $this->getData("status", null, 'trim'); $openid = $this->getData("openid", null, 'trim'); $from_uid = $this->getData("from_uid", null, 'trim'); $money = $this->getData("money", null, 'trim'); $is_auth = $this->getData("is_auth", null, 'trim'); $auth_type = $this->getData("auth_type", null, 'trim'); $auth_name = $this->getData("auth_name", null, 'trim'); $auth_time = $this->getData("auth_time", null, 'trim'); $auth_id = $this->getData("auth_id", null, 'trim'); $end_time = $this->getData("end_time", null, 'trim'); $verify = $this->getData("verify", null, 'trim'); $ctime = $this->getData("ctime", null, 'trim'); $mtime = $this->getData("mtime", null, 'trim');

    // 获取多条数据（参数只有ids，因为使用in没办法缓存，所以这么操作）
    public function getOneById($id, $fields = ['*'], $pk = 'id')
    {
        if(empty($id)){
            return [];
        }
        // 如果不要缓存 直接查询
        $getOneById = true;
        $is_cache   = $this->is_cache;
        if(empty($is_cache)){
            $info = $this->select($fields)->where($pk, $id)->first();
            $info = is_object($info) ? $info->toArray() : $info;
        } else{
            // 如果缓存 则查询缓存
            $args  = compact('id', 'fields', 'pk', 'getOneById');
            $cName = $this->cacheKey('show', $args);
            $info  = $this->cacheClass()->getCache($cName);
            // 检查是否已经绑定
            if($info){
                $this->checkBangShow($info, $cName);
            }
            if(empty($info)){
                // 查询
                $info = $this->where($pk, $id)->select($fields)->first();
                $info = is_object($info) ? $info->toArray() : $info;
                $this->addCacheShow($info, $cName, $info);
            }
        }

        // 各种查询后的操作

        // 1、头像
        // 2、认证类型


        return $info;
    }

    // 检查唯一性
    public function checkUser($data, $id = '')
    {

        $where = [];
        // username 唯一性
        if(!empty($data['username'])){
            $yzwhere = [['username', '=', $data['username']], ['status', '>=', 0]];
            if($id){
                $where = [['id', '<>', $id]];
            }
            $info = $this->where($where)->where($yzwhere)->first();
            if($info){
                return $this->return_false('该用户名已经存在！');
            }
        }


        // email 唯一性
        if(!empty($data['email'])){
            $yzwhere = [['email', '=', $data['email']], ['status', '>=', 0]];
            if($id){
                $where = [['id', '<>', $id]];
            }
            $info = $this->where($where)->where($yzwhere)->first();
            if($info){
                return $this->return_false('该邮箱已经存在！');
            }
        }

        // mobile 唯一性
        if(!empty($data['mobile'])){
            $yzwhere = [['mobile', '=', $data['mobile']], ['status', '>=', 0]];
            if($id){
                $where = [['id', '<>', $id]];
            }
            $info = $this->where($where)->where($yzwhere)->first();
            if($info){
                return $this->return_false('该手机号已经存在！');
            }
        }

        return $data;
    }

    // 添加验证
    public function checkData($data, $where = [])
    {
        // 随机码
        if($where && empty($data['password'])){
            unset($data['password']);
        } else{
            $salt = Str::random(4);
            if(empty($data['password'])){
                $data['password'] = 123456;
            }
            // 密码
            $data['salt']     = $salt;
            $data['password'] = $this->add_md5($data['password'], $salt);
        }

        // 整理角色
        if(empty($data['role'])){
            unset($data['role']);
        } else{
            $data['role'] = json_encode($data['role'], 1);
        }

        return $data;
    }

    // 修改密码
    public function onPassword($id, $password)
    {
        // 查询用户
        $where = ['id' => $id];
        $info  = $this->isCache(true)->oneFind($where);
        if(empty($info)){
            return $this->return_false('修改用户不存在！');
        }

        // 随机码
        $salt = $info['salt'];
        if(empty($salt)){
            $salt = random(4);
        }

        // 修改执行  密码
        $password = $this->add_md5($password, $salt);
        $updata   = ['salt' => $salt, 'password' => $password];
        $result   = $this->where($where)->update($updata);

        // 缓存操作
        $this->deleteCacheShow($info, $updata);

        return $result;
    }


    // 获取随机码  有时候需要唯一的随机码
    public function salt($number = 6, $isUnique = false)
    {
        $salt = Str::random($number);
        // 直接返回
        if(empty($isUnique)){
            return $salt;
        }

        // 生成唯一验证码
        $info = $this->select(['id', 'salt'])->where('salt', $salt)->first();
        if(empty($info)){
            return $salt;
        }

        // 如果随机码已经存在 则继续生成
        return $this->salt($number, $isUnique);
    }

    // 登录
    public function login($username, $password, $loginField = 'username')
    {
        // 获取用户信息
        $info = $this->where([$loginField => $username])->first();
        if(empty($info)){
            return $this->return_false('用户不存在！！');
        }
        if($info->status === 0){
            return $this->return_false('用户被禁止登录！！');
        }

        //var_dump($this->add_md5($password, $info->salt));
        // 验证密码
        if(!$this->ckeckPassword($password, $info->salt, $info['password'])){
            return $this->return_false('密码错误！！');
        }

        // 登录成功
        $user   = ['id' => $info->id, 'username' => $info->username, 'head_img' => $info->head_img, 'mobile' => $info->mobile, 'last_ip' => $info->last_ip, 'last_time' => $info->last_time,];
        $updata = ['last_ip' => request()->ip(), 'last_time' => LARAVEL_TIME,];
        $rst    = $this->where('id', $info->id)->update($updata);

        return $user;
    }

    // 注销
    public function cancel($uid)
    {
        // 查询（用于缓存操作）
        $userDb  = $this;
        $authDb  = new UserAuth();
        $newsDb  = new News();
        $eventDb = new Event();
        $nCommDb = new NewsComment();


        // 文章与活动
        $news     = $newsDb->where('uid', $uid)->get()->toArray();
        $events   = $eventDb->where('uid', $uid)->get()->toArray();
        $comments = $nCommDb->where('uid', $uid)->get()->toArray();

        // 课程与订单
        $courseDb = new Course();
        $orderDb  = new Order();
        $courses  = $courseDb->where('uid', $uid)->get()->toArray();
        $orders   = $orderDb->where('uid', $uid)->get()->toArray();

        // 收藏 评论
        $eCollect = new EventCollect();
        $uFanDb   = new UserFan();
        $collects = $eCollect->where('uid', $uid)->get()->toArray();
        $fans     = $uFanDb->where('uid', $uid)->get()->toArray();

        // 执行
        DB::beginTransaction();
        try{
            // 删除用户与认证
            $userDb->where('id', $uid)->delete(); // ->update(['status' => -1]);
            $authDb->where('uid', $uid)->delete(); // ->update(['verify' => -1]);

            // 删除活动与文章
            $newsDb->where('uid', $uid)->delete(); // ->update(['verify' => -1]);
            $eventDb->where('uid', $uid)->delete(); // ->update(['verify' => -1]);
            $nCommDb->where('uid', $uid)->delete(); // ->update(['verify' => -1]);

            // 删除课程与订单
            $courseDb->where('uid', $uid)->delete(); // ->update(['status' => -1]);
            $orderDb->where('uid', $uid)->delete(); // ->update(['verify' => -1, 'status' => -1,]);

            // 删除 收藏 评论
            $eCollect->where('uid', $uid)->delete(); // ->update(['status' => -1]);
            $uFanDb->where('uid', $uid)->delete(); // ->update(['status' => -1,]);

            DB::commit();
        } catch(\Exception $e){
            DB::rollBack();

            return $this->return_false($e->getMessage());
        }


        // 缓存整理：
        $userDb->deleteCacheShow(['id' => $uid]);
        $authDb->deleteCacheShow(['uid' => $uid]);
        $newsDb->deleteCacheList($news);
        $eventDb->deleteCacheList($events);
        $nCommDb->deleteCacheList($comments);
        $courseDb->deleteCacheList($collects);
        $uFanDb->deleteCacheList($fans);
        $uFanDb->deleteCacheList($fans);

        // TODO 以后在添加的该用户的相关信息

        return true;
    }

    // 检查用户认证
    // 检查 操作用户必须是认证用户
    public function checkUserAuth($myUid, $isSelf = true, $type = '')
    {
        $_self = $isSelf ? '您' : '用户';
        $user  = (new User())->isCache(true)->oneFind(['id' => $myUid]);
        if(empty($user)){
            return $this->return_false($_self.'不存在！');
        }
        if(empty($user['is_auth'])){
            return $this->return_false($_self.'不是认证用户！');
        }
        if($user['verify'] != 1){
            return $this->return_false($_self.'认证审核未通过！');
        }
        if($type && ($type != $user['auth_type'])){
            $msg = $type == 'school' ? '学校认证' : '机构认证';

            return $this->return_false($_self.'不是'.$msg.'！');
        }

        return $user;
    }

    // 加密密码
    public function add_md5($password, $salt = '')
    {
        return password_hash($password.$salt, PASSWORD_DEFAULT);
    }

    // 解密       相等返回 true，否则返回 false。
    public function ckeckPassword($password, $salt, $hash)
    {
        return password_verify($password.$salt, $hash);
    }


    // 定义验证操作
    public function rules()
    {
        $add = [
            'username' => 'required',
            'password' => 'required',
            'salt'     => 'required',
        ];

        $edit = [
        ];

        $info = [
            //'username'  => 'required',
            //'realname' => 'required',
        ];


        $rule = [
            //'score'     => 'required',
            //'password'  => 'required',
            //'nickname'  => 'required',
            //'head_img'  => 'required',
            //'mobile'    => 'required',
            //'email'     => 'required',
            //'sex'       => 'required',
            //'username'  => 'required',
            //'openid'    => 'required',
            //'city'      => 'required',
            //'reg_ip'    => 'required',
            //'last_ip'   => 'required',
            //'last_time' => 'required',
            //'sign'      => 'required',

            //'from_uid'  => 'required',
            //'money'     => 'required',
            //'auth_type' => 'required',
            //'auth_name' => 'required',
            //'auth_time' => 'required',
            //'auth_id'   => 'required',
            //'end_time'  => 'required',
            //'verify'    => 'required',
            //'is_auth' => 'required',
            'status' => ['in:-1,0,1,2'],
        ];


        $msg = [
            'id'        => '编号',
            'score'     => '积分',
            'username'  => '用户名（唯一且不变，用于阿特@操作）',
            'password'  => '密码',
            'nickname'  => '昵称（企业认证名称，因为程序中已经使用，所以不修改字段名）',
            'head_img'  => '头像',
            'mobile'    => '手机号',
            'email'     => '邮箱',
            'sex'       => '0-保密1-男 2-女',
            'city'      => '所在城市',
            'reg_ip'    => '注册ip',
            'last_ip'   => '上次登录ip',
            'last_time' => '上次登录时间',
            'sign'      => '个性签名',
            'status'    => '状态 0-禁用 1-正常 -1-删除',
            'openid'    => '微信openid',
            'from_uid'  => '邀请人',
            'money'     => '资金余额',
            'is_auth'   => '是否认证（1-是）',
            'auth_type' => '认证类型',
            'auth_name' => '认证名称',
            'auth_time' => '认证时间',
            'auth_id'   => '认证ID（认证后写入）',
            'end_time'  => '认证结束时间',
            'verify'    => '是否审核（认证用户才需要审核）（1-是,审核通过，2-审核不通过）',
            'ctime'     => '创建时间',
            'mtime'     => '修改时间',
        ];

        return ['rule' => $rule, 'msg' => $msg, 'add' => $add, 'info' => $info];
    }

}
